#include "session_data.h"
#include "qtch/config.h"
#include "qtch/worker.h"

namespace qtch {

namespace http{

ConfigVar<int64_t>::ptr g_sessionDataExpireTimeMs = Config::LookUp<int64_t>("tcp.http.session_expire_ms",3600,"session data expire time(ms)");

static int64_t s_sessionDataExpireTimeMs;

struct _QtchHttpSessopmDataInit{

    _QtchHttpSessopmDataInit(){
        s_sessionDataExpireTimeMs = g_sessionDataExpireTimeMs->getValue();
        g_sessionDataExpireTimeMs->addListener([](const int64_t &old_value, const int64_t &new_value){
            s_sessionDataExpireTimeMs = new_value;
        });
    }
};
static _QtchHttpSessopmDataInit _init;

SessionData::SessionData() {
    m_lastAccessTime = time(0);

}

void SessionData::del(const std::string& key) {
    RWMutexType::WriteLock lock(m_mutex);
    m_data.erase(key);
}

bool SessionData::has(const std::string& key) {
    RWMutexType::ReadLock lock(m_mutex);
    auto it = m_data.find(key);
    return it!=m_data.end();
}

void SessionDataManager::add(SessionData::ptr data) {
    RWMutexType::WriteLock lock(m_mutex);
    m_data[data->getId()] = data;
}

void SessionDataManager::del(const std::string& id) {
    RWMutexType::WriteLock lock(m_mutex);
    m_data.erase(id);
}

void SessionDataManager::del(std::vector<std::string>& ids){
    RWMutexType::WriteLock lock(m_mutex);
    for(auto& i:ids){
        m_data.erase(i);
    }
}

SessionData::ptr SessionDataManager::get(const std::string& id) {
    RWMutexType::ReadLock lock(m_mutex);
    auto it = m_data.find(id);
    if(it==m_data.end()){
        return nullptr;
    }
    it->second->setLastAcccessTime(time(0));
    return it->second;
}

void SessionDataManager::check(int64_t ts) {
    uint64_t now = time(0) - ts;
    std::vector<std::string> keys;
    {
        RWMutexType::ReadLock lock(m_mutex);
        for(auto it = m_data.begin(); it!=m_data.end();++it){
            if(it->second->getLastAccsessTime() < now){
                keys.push_back(it->second->getId());
            }
        }
    }
    del(keys);

}

void SessionDataManager::init(){
    // 增加删除长时间未用的session data 的定时器
    qtch::WorkerMgr::GetInstance()->getAsIOManager("main")->addTimer(3000,[](){
        SessionDataMgr::GetInstance()->check(s_sessionDataExpireTimeMs);
    },true);
}

}

}